<script setup>
  import { ref, reactive } from 'vue';
  import { useRouter } from 'vue-router';
  import { useStore } from 'vuex';
  import { CODE_WAIT_TIME } from '@/constants';//60s
  import { throttle } from 'lodash';
  import * as strategy from '@/constants/strategy';
  import { ElMessage, ElMessageBox } from 'element-plus';
  import * as userApi from '@/api/user';


  const store = useStore();
  const activeName = ref('first');
  const form = ref(null);
  const router = useRouter();
  const countDown = ref(CODE_WAIT_TIME);

  // const account = localStorage.getItem('account') || '';
  // const password = localStorage.getItem('password') || '';
  // const mobile = localStorage.getItem('mobile') || '';
  const isMemo = localStorage.getItem('isMemo') || false;

  const params = reactive({
    account : 'abcdefghijklmn',
    password : '123456',
    mobile : '13812345678',
    code: '',
    isMemo,
  });
  function accountChecker(_, value, cb) {
    if (!strategy.ACCOUNT.test(value.trim())) {
      cb(new Error('账号格式错误 应为字母开头 共6-20个字符'));
    } else {
      cb();
    }
  }
  function mobileChecker(_, value, cb) {
    if (!strategy.MOBILE.test(value.trim())) {
      cb(new Error('手机号格式错误'));
    } else {
      cb();
    }
  }

  function codeChecker(_, value, cb) {
    if (!strategy.CODE.test(value.trim())) {
      cb(new Error('验证码格式错误'));
    } else {
      cb();
    }
  }

  const rules = reactive({
    account: [{ validator: accountChecker, trigger: 'blur' }],
    mobile: [{ validator: mobileChecker, trigger: 'blur' }],
    code: [{ validator: codeChecker, trigger: 'blur' }],
  });
  let tmpCode = '';
  //密码登录
  function passwordLogin() {
    if (!strategy.ACCOUNT.test(params.account) || !(imageCode === params.code) || !strategy.PASSWORD.test(params.password)) {
      ElMessage.error('请输入正确的信息');
      return;
    }
    userApi.passwordLogin({
      captcha: params.code,
      password:params.password,
      userName:params.account
    })
    .then(()=>{
      ElMessage.success('登录成功');
      router.push('/userPage');
    })
    .catch((err)=>{
      return err;
    })
}
// 验证码登录
function phoneLogin() {
  // console.log(strategy.MOBILE.test(params.mobile))
  // console.log((phoneCode === params.code && phoneCode !== ''))
  if (!strategy.MOBILE.test(params.mobile) || !(tmpCode === params.code && tmpCode !== '')) {
    ElMessage.error('请输入正确的信息');
    return;
  }
  userApi.phoneLogin({
    phone:params.mobile,
    phoneCode:params.code
  })
  .then(()=>{
    ElMessage.success('登录成功');
    router.push('/userPage');
  })
  .catch((err)=>{
    return err;
  })
}
let showMask = ref(false);
// 点击获取验证码时判断
function sendCode() {
  if (!strategy.MOBILE.test(params.mobile)) {
    return;
  }
  // 成功
  sendCodeWithCheckSuccess();
}
// 发送验证码
const sendCodeWithCheckSuccess = throttle(() => {
  let timer = null;
  showMask.value = true;
  userApi.getPhoneCode({
    phone: params.mobile,
  })
    .then((res) => {
      tmpCode = res.data.data;
      ElMessageBox.alert(`手机验证码为：${ res.data.data }`, '提示', {
        confirmButtonText: '确定',
        callback: () => {
          ElMessage({
            type: 'info',
            message: ``,
          })
        },
      })
    })
    .catch((msg) => {
      sendCodeWithCheckSuccess.cancel();
      clearInterval(timer);
      countDown.value = CODE_WAIT_TIME;
      ElMessage({
        message: msg,
        type: 'error',
      });
    });
  countDown.value = CODE_WAIT_TIME - 1;
  timer = setInterval(() => {
    countDown.value--;
    if (countDown.value < 1) {
      clearInterval(timer);
      countDown.value = CODE_WAIT_TIME;
      showMask.value = false;
    }
  }, 1000);
}, 500);

// 退出登录
function outLogin() {
  router.push('/');
}
// 点击切换登录方式
function handleClick() {
}
let imageCode = '';
const verify = ref(null)
const state = reactive({
  pool: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890', // 字符串
  width: 120,
  height: 40,
  imgCode: ''
})
// 初始化绘制图片验证码
onMounted(() => {
  state.imgCode = draw()
})

// 点击图片重新绘制
const handleDraw = () => {
  imageCode = ''
  state.imgCode = draw()
}
// 随机数
const randomNum = (min, max) => {
  return parseInt(Math.random() * (max - min) + min)
}
// 随机颜色
const randomColor = (min, max) => {
  const r = randomNum(min, max)
  const g = randomNum(min, max)
  const b = randomNum(min, max)
  return `rgb(${r},${g},${b})`
}
// 绘制图片
const draw = () => {
  // 3.填充背景颜色，背景颜色要浅一点
  const ctx = verify.value.getContext('2d')
  // 填充颜色
  ctx.fillStyle = randomColor(180, 230)
  // 填充的位置
  ctx.fillRect(0, 0, state.width, state.height)
  // 定义paramText
  let imgCode = ''
  // 4.随机产生字符串，并且随机旋转
  for (let i = 0; i < 4; i++) {
    // 随机的四个字
    const text = state.pool[randomNum(0, state.pool.length)]
    imageCode += text
    imgCode += text
    // 随机的字体大小
    const fontSize = randomNum(18, 40)
    // 字体随机的旋转角度
    const deg = randomNum(-30, 30)
    /*
      * 绘制文字并让四个文字在不同的位置显示的思路 :
      * 1、定义字体
      * 2、定义对齐方式
      * 3、填充不同的颜色
      * 4、保存当前的状态（以防止以上的状态受影响）
      * 5、平移translate()
      * 6、旋转 rotate()
      * 7、填充文字
      * 8、restore出栈
      * */
    ctx.font = fontSize + 'px Simhei'
    ctx.textBaseline = 'top'
    ctx.fillStyle = randomColor(80, 150)
    /*
      * save() 方法把当前状态的一份拷贝压入到一个保存图像状态的栈中。
      * 这就允许您临时地改变图像状态，
      * 然后，通过调用 restore() 来恢复以前的值。
      * save是入栈，restore是出栈。
      * 用来保存Canvas的状态。save之后，可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。 restore：用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。
      *
      * */
    ctx.save()
    ctx.translate(30 * i + 15, 15)
    ctx.rotate((deg * Math.PI) / 180)
    // fillText() 方法在画布上绘制填色的文本。文本的默认颜色是黑色。
    // 请使用 font 属性来定义字体和字号，并使用 fillStyle 属性以另一种颜色/渐变来渲染文本。
    // context.fillText(text,x,y,maxWidth);
    ctx.fillText(text, -15 + 5, -15)
    ctx.restore()
  }
  // 5.随机产生5条干扰线,干扰线的颜色要浅一点
  for (let i = 0; i < 5; i++) {
    ctx.beginPath()
    ctx.moveTo(randomNum(0, state.width), randomNum(0, state.height))
    ctx.lineTo(randomNum(0, state.width), randomNum(0, state.height))
    ctx.strokeStyle = randomColor(180, 230)
    ctx.closePath()
    ctx.stroke()
  }
  // 6.随机产生40个干扰的小点
  for (let i = 0; i < 40; i++) {
    ctx.beginPath()
    ctx.arc(randomNum(0, state.width), randomNum(0, state.height), 1, 0, 2 * Math.PI)
    ctx.closePath()
    ctx.fillStyle = randomColor(150, 200)
    ctx.fill()
  }
  return imgCode
}
  // return {
  //   ...toRefs(state),
  //   verify,
  //   handleDraw
  // }
</script>

<template>
  <!-- 通过rules定义校验规则
      required:必填
      message:未填时触发报错信息
      trigger:触发器,失去焦点是触发
      pattern:正则 -->
  <div class="login">
    <div class="login-title">
      <i-ep-close @click="outLogin"/>
    </div>
    <div class="login-main">
      <img src="../../assets/style/Snipaste_2022-09-27_12-46-14.png" alt="">
      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
        <el-tab-pane label="验证码登录" name="first">
          <el-form
            ref="form"
            :rules="rules"
            :model="params"
          >
            <!-- 验证码登录 -->
            <el-form-item prop="mobile">
              <el-input
                v-model="params.mobile"
                placeholder="手机号"
                class="code-input"
              >
                <template #append class="sendCodeInput">
                  <div :class="showMask? 'mask' : ''"></div>
                  <el-button
                    text
                    @click="sendCode"
                    :class="strategy.MOBILE.test(params.mobile)? 'code-btn' : ''"
                  >
                    {{ countDown === CODE_WAIT_TIME?'获取验证码':`重新获取(${ countDown }s)` }}
                  </el-button>
                </template>
              </el-input>
            </el-form-item>
            <el-form-item prop="code">
              <el-input
                v-model="params.code"
                placeholder="验证码"
              >
              </el-input>
            </el-form-item>
            <el-form-item>
              <span class="hint">温馨提示：未注册的手机号，验证后将自动注册账户,且代表已同意<a href="javascript:;">《服务协议与隐私政策》</a></span>
            </el-form-item>
            <el-button
              type="primary"
              @click="phoneLogin"
              class="login-btn"
            >
              登录
            </el-button>
          </el-form>
        </el-tab-pane>
        <el-tab-pane label="密码登录" name="second">
          <el-form
            ref="form"
            :rules="rules"
            :model="params"
          >
            <!-- 账号登录 -->
            <el-form-item prop="account">
              <el-input
                v-model="params.account"
                placeholder="用户名"
              >
              </el-input>
            </el-form-item>
            <el-form-item prop="password">
              <el-input
                v-model="params.password"
                type="password"
                placeholder="密码"
                show-password
              >
              </el-input>
            </el-form-item>
            <el-form-item prop="code">
              <el-input
                v-model="params.code"
                placeholder="验证码"
              >
              <template #append>
                <div class="img-verify">
                  <canvas ref="verify" :width="120" :height="42" @click="handleDraw"></canvas>
                </div>
                <!-- <div class="change-image" @click="changeCode">1234{{ tmpCode }}</div> -->
              </template>
              </el-input>
            </el-form-item>
            <el-button
              type="primary"
              @click="passwordLogin"
              class="login-btn"
            >
              登录
            </el-button>
          </el-form>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.sendCodeInput {
  position: relative;
}
.mask {
  width: 120px;
  height: 42px;
  background-color: rgb($color: #f5f7fa, $alpha: 0.1);
  position: absolute;
  display: block;
}
// :deep(.el-overlay.is-message-box) {
//   z-index: 2005;
//   position: absolute;
//   top: 50%;
//   left: 50%;
//   background: pink;
//   padding: 20px 40px;
//   display: flex;
//   justify-content: center;
//   align-items: center;
//   transform: translate(-50%, -50%);
// }
:deep([data-v-2bf2fc29] .el-input-group__append) {
  height: 42px;
  width: 120px;
  box-sizing: border-box;
  overflow: hidden;
  position: relative;
}
.img-verify {
  width: 120px;
  height: 42px;
}
.img-verify canvas{
  width: 120px;
  height: 44px;
  cursor: pointer;
}
  :deep(.el-input-group__append){
    cursor: pointer;
    .change-image {
      width: 100%;
      height: 95%;
      background-color: #f5f7fa;
      color: red;
      text-align: center;
      line-height: 42px;
    }
  }
  .login {
    box-sizing: border-box;
    width: 375px;
    height: 100%;
    .login-title {
      width: 375px;
      height: 50px;
      color: #dd2727;
      padding: 5px 10px;
      box-sizing: border-box;
      font-size: 30px;
    }
    .login-main {
      text-align: center;
      padding: 10px 0;
      .code-input .code-btn {
        color: #cc3b32;
      }
    }
    :deep(.el-tabs__nav) {
      float: none;
    }
    :deep(.el-tabs__nav-wrap::after) {
      content: '';
      height: 0;
    }
    // 表单
    form {
      padding: 0 40px;
      line-height: 50px;
      .hint {
        font-size: 12px;
        color: #999;
        display: block;
        box-sizing: border-box;
        & a {
          color: #cc3b32;
        }
      }
      // 登录按钮
      .login-btn {
        height: 40px;
        width: 100%;
        background-color: #cc3b32;
      }
      :deep(.el-input__inner) {
        height: 40px;
      }
    }
  }
</style>

